package com.anandsoftware.security.ui;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;

import com.anandsoftware.application.ApplicationContext;
import com.anandsoftware.application.ApplicationContextInitializationFailed;
import com.anandsoftware.db.io.DatabaseIO;
import com.anandsoftware.db.type.DatabaseType;
import com.anandsoftware.security.ui.task.RegisterationTask;
import com.anandsoftware.service.AuthenticateService;
import com.anandsoftware.service.impl.AuthenticateServiceImpl;
import com.anandsoftware.system.SystemInformationUtill;

public class SystemRegisteration {

	public JFrame frmSoftwareRegistation;
	public JTextField textField;
	public JLabel lblMessage = new JLabel("Initialized.. ");
	public JLabel messageIcon = new JLabel("");
	public int progress = 0;
	public JProgressBar progressBar = null;
	public JTextField txtCdKey;
	public final int STEP = 25;
	public final int CDKEY_LENGTH = 24;
	public final int DATABASE_NAME_LENGTH = 4;
	public JTextField txtDbUserName;
	public JPasswordField txtDbPassword;
	String cdKey = "";
	public JTextField txtDbName;
	public JComboBox comboVendor;
	JButton btnCheck;

	boolean propertyLoaded = false;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					SystemRegisteration window = new SystemRegisteration();
					window.frmSoftwareRegistation.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public SystemRegisteration() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmSoftwareRegistation = new JFrame();
		frmSoftwareRegistation.setTitle("Software Registation");
		frmSoftwareRegistation.setResizable(false);
		frmSoftwareRegistation
				.setIconImage(Toolkit
						.getDefaultToolkit()
						.getImage(
								SystemRegisteration.class
										.getResource("/com/anandsoftware/security/ui/resources/image/fevicon.png")));
		frmSoftwareRegistation.getContentPane().setBackground(Color.WHITE);
		frmSoftwareRegistation.getContentPane().setLayout(null);

		JLabel label = new JLabel("");
		label.setIcon(new ImageIcon(
				SystemRegisteration.class
						.getResource("/com/anandsoftware/security/ui/resources/image/business-background.png")));
		label.setBounds(10, 11, 281, 252);
		frmSoftwareRegistation.getContentPane().add(label);

		JLabel lblAnandSoftwareRegistration = new JLabel(
				"Anand Software Registration");
		lblAnandSoftwareRegistration.setFont(new Font("Times New Roman",
				Font.BOLD, 16));
		lblAnandSoftwareRegistration.setBackground(Color.WHITE);
		lblAnandSoftwareRegistration.setBounds(206, 22, 253, 25);
		frmSoftwareRegistation.getContentPane().add(
				lblAnandSoftwareRegistration);

		progressBar = new JProgressBar();
		progressBar.setFont(new Font("Times New Roman", Font.PLAIN, 11));
		progressBar.setBackground(Color.WHITE);
		progressBar.setStringPainted(true);
		progressBar.setForeground(new Color(221, 160, 221));
		progressBar.setBounds(10, 383, 594, 14);
		frmSoftwareRegistation.getContentPane().add(progressBar);

		JLabel lblOverAllProgress = new JLabel("Over All Progress");
		lblOverAllProgress.setBounds(271, 407, 125, 14);
		frmSoftwareRegistation.getContentPane().add(lblOverAllProgress);

		JPanel mainPanel = new JPanel();
		mainPanel.setBackground(Color.WHITE);
		mainPanel.setBounds(258, 58, 346, 252);
		frmSoftwareRegistation.getContentPane().add(mainPanel);
		mainPanel.setLayout(null);

		JButton btnBrowseProperty = new JButton("Browse");
		btnBrowseProperty.setBounds(10, 11, 115, 23);
		mainPanel.add(btnBrowseProperty);
		btnBrowseProperty.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setFileFilter(new PropertyFileFilter());
				fileChooser.showOpenDialog(frmSoftwareRegistation);
				File propertyFile = fileChooser.getSelectedFile();
				textField.setText(propertyFile.getName());
				if (!loadContext(propertyFile.getAbsolutePath())) {
					propertyLoaded = false;
					lblMessage.setText("Error In Property File.");
					setErrorIcon(true);
				} else {
					propertyLoaded = true;
					progress = STEP;
					progressBar.setValue(progress);
					lblMessage.setText("All Property Initialized");
					setErrorIcon(false);
				}
			}
		});
		btnBrowseProperty.setToolTipText("Select Property File");

		textField = new JTextField();
		textField.setBounds(135, 12, 201, 20);
		mainPanel.add(textField);
		textField.setEditable(false);
		textField.setColumns(10);

		JLabel lblCdkey = new JLabel("CD-Key");
		lblCdkey.setBounds(10, 45, 115, 14);
		mainPanel.add(lblCdkey);

		txtCdKey = new JTextField();
		txtCdKey.setToolTipText("Enter Your Software CD-Key Here");
		txtCdKey.setBounds(135, 43, 201, 20);
		mainPanel.add(txtCdKey);
		txtCdKey.setColumns(10);

		JButton btnRegister = new JButton("Register");
		btnRegister.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				startRegistrationProcess();
			}
		});
		btnRegister.setBounds(135, 197, 89, 23);
		mainPanel.add(btnRegister);

		JLabel lblDatabaseProvider = new JLabel("Database Provider");
		lblDatabaseProvider.setBounds(10, 77, 115, 14);
		mainPanel.add(lblDatabaseProvider);

		comboVendor = new JComboBox();
		comboVendor.setBounds(135, 74, 201, 20);
		mainPanel.add(comboVendor);
		comboVendor.setModel(new DefaultComboBoxModel(new String[] { "MYSQL",
				"MICROSOFT-ODBC", "ORACLE", "SQLITE" }));
		comboVendor.setSelectedIndex(0);
		comboVendor.setToolTipText("Select Database Engine");

		JLabel lblDatabaseUsername = new JLabel("Database User");
		lblDatabaseUsername.setBounds(10, 136, 115, 14);
		mainPanel.add(lblDatabaseUsername);

		txtDbUserName = new JTextField();
		txtDbUserName.setToolTipText("Enter Database Username here");
		txtDbUserName.setBounds(135, 133, 201, 20);
		mainPanel.add(txtDbUserName);
		txtDbUserName.setColumns(10);

		JLabel lblDatabasePassword = new JLabel("Database Password");
		lblDatabasePassword.setBounds(10, 169, 115, 14);
		mainPanel.add(lblDatabasePassword);

		txtDbPassword = new JPasswordField();
		txtDbPassword.setToolTipText("Eneter Database Password Here");
		txtDbPassword.setBounds(135, 164, 201, 20);
		mainPanel.add(txtDbPassword);

		JLabel lblDatabaseName = new JLabel("Database Name");
		lblDatabaseName.setBounds(10, 108, 108, 14);
		mainPanel.add(lblDatabaseName);

		txtDbName = new JTextField();
		txtDbName.setToolTipText("Enter Database Username here");
		txtDbName.setColumns(10);
		txtDbName.setBounds(135, 105, 201, 20);
		mainPanel.add(txtDbName);

		btnCheck = new JButton("Check");
		btnCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {

				String username = txtDbUserName.getText().trim();
				String password = new String(txtDbPassword.getPassword())
						.trim();
				String dbName = txtDbName.getText().trim();
				int vendorID = comboVendor.getSelectedIndex();
				int vendor = 0;
				switch (vendorID) {
				case 0:
					vendor = DatabaseType.MYSQL;
				case 1:
					vendor = DatabaseType.MICROSOFT_ACCESS;
				case 2:
					vendor = DatabaseType.ORACLE;
				case 3:
					vendor = DatabaseType.SQLITE;
				}

				DatabaseIO dbIO = new DatabaseIO();
				dbIO.init(dbName, username, password, vendor);

				AuthenticateService authService = new AuthenticateServiceImpl();
				if (authService.authenticateOffline(
						SystemInformationUtill.getSystemInformation(), dbIO)) {
					setErrorIcon(false);
					lblMessage.setText("Authentication Successful");
				} else {
					setErrorIcon(true);
					lblMessage
							.setText("Authentication Failed (Register Again)");
				}
				// dbIO.closeDatabase();
			}
		});
		btnCheck.setEnabled(false);
		btnCheck.setBounds(247, 197, 89, 23);
		mainPanel.add(btnCheck);

		JPanel messagePanel = new JPanel();
		messagePanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		messagePanel.setBackground(Color.WHITE);
		messagePanel.setBounds(10, 321, 594, 53);
		frmSoftwareRegistation.getContentPane().add(messagePanel);
		messagePanel.setLayout(null);

		messagePanel.add(messageIcon);
		setErrorIcon(false);
		lblMessage.setFont(new Font("Times New Roman", Font.BOLD, 18));
		lblMessage.setBounds(103, 11, 481, 30);
		messagePanel.add(lblMessage);

		JLabel lblCopyrightAnand = new JLabel("Copyright @ Anand Software");
		lblCopyrightAnand.setBounds(10, 246, 238, 14);
		frmSoftwareRegistation.getContentPane().add(lblCopyrightAnand);

		JLabel lblHttpwwwanandsoftwarecom = new JLabel(
				"http://www.anandsoftware.com");
		lblHttpwwwanandsoftwarecom.setBounds(10, 260, 238, 14);
		frmSoftwareRegistation.getContentPane().add(lblHttpwwwanandsoftwarecom);
		frmSoftwareRegistation.setBounds(100, 100, 620, 460);
		frmSoftwareRegistation.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private void startRegistrationProcess() {
		if (!propertyLoaded) {
			lblMessage.setText("Load Property File First!");
			setErrorIcon(true);
			return;
		}

		cdKey = txtCdKey.getText().trim();
		if (cdKey.length() != CDKEY_LENGTH) {
			lblMessage.setText("Invalid Key Size!");
			setErrorIcon(true);
			return;
		}

		if (txtDbName.getText().trim().length() < DATABASE_NAME_LENGTH) {
			lblMessage.setText("Invalid Database Name (must be of minimum "
					+ DATABASE_NAME_LENGTH + " letters)");
			setErrorIcon(true);
			return;
		}
		progress = STEP;
		progressBar.setValue(progress);

		RegisterationTask task = new RegisterationTask(this, cdKey);
		task.initProgress(progress);

		task.addPropertyChangeListener(new PropertyChangeListener() {

			@Override
			public void propertyChange(PropertyChangeEvent evt) {
				if ("progress" == evt.getPropertyName()) {
					progress = (Integer) evt.getNewValue();
					progressBar.setValue(progress);
				}
			}
		});
		task.execute();
		btnCheck.setEnabled(true);
	}

	public void setErrorIcon(boolean action) {
		if (action) {
			messageIcon
					.setIcon(new ImageIcon(
							SystemRegisteration.class
									.getResource("/com/anandsoftware/security/ui/resources/image/errorIcon.png")));

		} else {
			messageIcon
					.setIcon(new ImageIcon(
							SystemRegisteration.class
									.getResource("/com/anandsoftware/security/ui/resources/image/correct-icon.png")));
		}
		messageIcon.setBounds(21, 0, 48, 52);
	}

	private boolean loadContext(String path) {
		try {
			new ApplicationContext(path);
			return true;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ApplicationContextInitializationFailed e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return false;
	}
}
